

package ru.samgtu.wst.ui.swing;

import ru.samgtu.wst.model.ConversationEvent;
import ru.samgtu.wst.model.ConversationID;
import ru.samgtu.wst.model.ConversationListener;
import ru.samgtu.wst.model.ConversationModel;

import javax.swing.AbstractListModel;
import javax.swing.SwingUtilities;

import java.util.logging.Logger;


public class ConversationListModel extends AbstractListModel {

	private ConversationModel _model = null;
	private Listener _listener = new Listener();
	private int _size = 0;

	private Logger _logger = Logger.getLogger(getClass().getName());

	/** Creates a new instance of ConversationTableModel */
	public ConversationListModel(ConversationModel model) {
		_model = model;
		_model.addConversationListener(_listener);
		fireContentsChanged(this, 0, getSize());
	}

	public Object getElementAt(int index) {
		return getConversationAt(index);
	}

	public int getIndexOfConversation(ConversationID id) {
		return _model.getIndexOfConversation(id);
	}

	public int getConversationCount() {
		return _model.getConversationCount();
	}

	public ConversationID getConversationAt(int index) {
		return _model.getConversationAt(index);
	}

	public int getSize() {
		if (_model == null) {
			return 0;
		}
		_size = getConversationCount();
		return _size;
	}

	protected void addedConversation(ConversationEvent evt) {
		ConversationID id = evt.getConversationID();
		int row = getIndexOfConversation(id);
		if (row > -1) {
			fireIntervalAdded(this, row, row);
		}
	}

	protected void changedConversation(ConversationEvent evt) {
		ConversationID id = evt.getConversationID();
		int row = getIndexOfConversation(id);
		if (row > -1) {
			fireContentsChanged(this, row, row);
		}
	}

	protected void removedConversation(ConversationEvent evt) {
		ConversationID id = evt.getConversationID();
		int row = getIndexOfConversation(id);
		if (row > -1) {
			fireIntervalRemoved(this, row, row);
		}
	}

	protected void conversationsChanged() {
		if (_size > 0) {
			fireIntervalRemoved(this, 0, _size);
		}
		fireIntervalAdded(this, 0, getSize());
	}

	private class Listener implements ConversationListener {

		public void conversationAdded(final ConversationEvent evt) {
			if (SwingUtilities.isEventDispatchThread()) {
				ConversationListModel.this.addedConversation(evt);
			} else {
				try {
					SwingUtilities.invokeAndWait(new Runnable() {
						public void run() {
							ConversationListModel.this.addedConversation(evt);
						}
					});
				} catch (Exception e) {
					_logger.warning("Exception! " + e);
				}
			}
		}

		public void conversationChanged(final ConversationEvent evt) {
			if (SwingUtilities.isEventDispatchThread()) {
				ConversationListModel.this.changedConversation(evt);
			} else {
				try {
					SwingUtilities.invokeAndWait(new Runnable() {
						public void run() {
							ConversationListModel.this.changedConversation(evt);
						}
					});
				} catch (Exception e) {
					_logger.warning("Exception! " + e + " : "
							+ e.getStackTrace()[0]);
				}
			}
		}

		public void conversationRemoved(final ConversationEvent evt) {
			if (SwingUtilities.isEventDispatchThread()) {
				ConversationListModel.this.removedConversation(evt);
			} else {
				try {
					SwingUtilities.invokeAndWait(new Runnable() {
						public void run() {
							ConversationListModel.this.removedConversation(evt);
						}
					});
				} catch (Exception e) {
					_logger.warning("Exception! " + e);
				}
			}
		}

		public void conversationsChanged() {
			if (SwingUtilities.isEventDispatchThread()) {
				ConversationListModel.this.conversationsChanged();
			} else {
				try {
					SwingUtilities.invokeAndWait(new Runnable() {
						public void run() {
							ConversationListModel.this.conversationsChanged();
						}
					});
				} catch (Exception e) {
					_logger.warning("Exception! " + e + " : "
							+ e.getStackTrace()[0]);
					e.printStackTrace();
				}
			}
		}

	}

}
